import os
import fh
import wx
import wx.stc

from debug  import here
from base   import *

settings=fh.settings

# https://sourceforge.net/tracker/?func=detail&atid=109863&aid=1762871&group_id=9863
BUG_1 = wx.Platform == '__WXMAC__'#BUG_1=False

settings['textbar.location']='left'
settings['textbar.location :type']=('left','right')

class MainPanel(wx.Panel):
	"""
	Contains all the documents, relays messages between doc.text and doc.textbar
	"""

	def __init__(me,parent):
		wx.Panel.__init__(me,parent,id=-1)
		
		fh.main_panel=me
		
		szr=wx.BoxSizer(wx.HORIZONTAL)		me.SetSizer(szr)		me.SetAutoLayout(True)
		
		if BUG_1:
			# make cursor go to default when it leaves STC
			szr2=wx.BoxSizer(wx.HORIZONTAL)
			szr.Add(szr2,1,wx.TOP|wx.EXPAND,3)
			szr=szr2

		
		me.Bind(wx.stc.EVT_STC_PAINTED,    me.OnTextPainted)
		me.Bind(wx.stc.EVT_STC_MODIFIED,   me.OnTextModified)
		me.Bind(wx.stc.EVT_STC_CHARADDED,  me.OnTextCharAdded)
		
		me.szr          = szr
		me.docs         = []
		me.text_id_TO_doc = {}
		me.doc_w_focus  = None
		me.events       = fh.EventSet('ActiveDocSwitch')
		
		me.SetOwnBackgroundColour(wx.Colour(100,100,100))

		me.new()
		
		if fh.debug.ON:
			for file in fh.debug.files:
				me.open(file)
				
    # --- Relay events from text to textbar

	def OnTextPainted(me,e):
		me.text_id_TO_doc[e.GetId()].OnTextPainted(e)
		
	def OnTextModified(me,e):
		me.text_id_TO_doc[e.GetId()].OnTextModified(e)
		
	def OnTextCharAdded(me,e):
		me.text_id_TO_doc[e.GetId()].OnTextCharAdded(e)
    # ----

	def new(me):			
		doc=fh.Document(me)
		
		me.docs.append(doc)
		me.text_id_TO_doc[doc.text.GetId()]=doc
		
		doc.events.Unsaved+=me.on_unsaved
		#doc.EVENTS.unsaved += me.on_unsaved
		doc.textbar.events.Activate+=me.on_doc_textbar_activate
		#doc.textbar.EVENTS.activate.subscribe(me.on_doc_textbar_activate)
		#doc.textbar.EVENTS.activate += me.on_doc_textbar_activate
		
		#doc.e.unsaved += me.on_unsaved
		
		#doc._events_.unsaved.call( me.on_unsaved )
		#doc.textbar._events_.activate.call( me.on_doc_textbar_activate )
		
		if settings['textbar.location']=='right':
			me.szr.Add(doc.textbar,0,wx.EXPAND|wx.LEFT,1)
			me.szr.Insert(0,doc.text,1,wx.EXPAND)
		elif settings['textbar.location']=='left':
			me.szr.Insert(0,doc.textbar,0,wx.EXPAND|wx.LEFT,1)
			me.szr.Add(doc.text,1,wx.EXPAND)					me.szr.Layout()
		
		me._expand(doc)
		
		me._set_title()
		
	def _expand(me,doc):
		expanding   = doc
		collapsing  = me.doc_w_focus
 
		if collapsing is not None:
			collapsing.activate(False)
			#print '* detaching',collapsing
			me.szr.Show(collapsing.text,False)
			#me.szr.Layout()
			#me.szr.Replace(collapsing.text,expanding.text)
		
		#print '* adding',expanding
		#me.szr.Insert(0,expanding.text,1,wx.EXPAND)
		me.szr.Show(expanding.text,True)
			
		me.szr.Layout()
		
		me.doc_w_focus=expanding
		expanding.activate(True)
		
		me._set_title()
		
		me.events.ActiveDocSwitch(src=me,old_doc=collapsing,new_doc=doc)
		
	def _fix_doc_order_after_doc_w_focus_name_change(me):
		return
		def local_cmp_function(x,y):
			if x.file is None or y.file is None:
				return -1
			return cmp(os.path.basename(x.file),os.path.basename(y.file))
		old_position=me.docs.index(me.doc_w_focus)
		me.docs.sort(local_cmp_function)
		new_position=me.docs.index(me.doc_w_focus)
		
		if old_position==new_position:
			return
			
		me.szr.Detach(me.doc_w_focus.textbar)
		me.szr.Insert(new_position,me.doc_w_focus.textbar,0,wx.EXPAND)
		me.szr.Layout()
	
	def yes_no_cancel(me,message,title='A Message Box'):
		d = wx.MessageDialog(me,message,title, wx.YES_NO | wx.YES_DEFAULT | wx.CANCEL | wx.ICON_INFORMATION)
		return d.ShowModal()
	
	def _close_n_no_new(me):
		if me.doc_w_focus.modified and not debug.on:
			save=me.yes_no_cancel('Save file first?')
			if save==CANCEL:
				return CANCEL
			if save==YES:
				if me.doc_w_focus.save()<>OK:
					return CANCEL
		
		szr=me.GetSizer()
		szr.Detach(me.doc_w_focus.textbar)
		szr.Detach(me.doc_w_focus.text)
		szr.Layout()
		
		me.docs.remove(me.doc_w_focus)
		del me.text_id_TO_doc[me.doc_w_focus.text.GetId()]
		
		me.doc_w_focus.Destroy()
		me.doc_w_focus=None
		
		return OK
		
	def close(me):
		if me._close_n_no_new()<>OK:
			return CANCEL
		if len(me.docs)==0:
			me.new()
		else:
			me._expand(me.docs[-1]) # ?? use LRU
		return OK
		
	def exit(me):
		if fh.debug.ON:
			return OK
			
		some_unsaved=False
		for doc in me.docs:
			if doc.modified:
				some_unsaved=True
				break
				
		if some_unsaved:
			save=me.yes_no_cancel('Save files first?')
			if save==CANCEL:
				return CANCEL
			if save==YES:
				for doc in me.docs:
					if doc.modified and doc.save()<>OK:
						return CANCEL
		
		return OK
		
	def open(me,file=None):
		
		if file is None:
			d=wx.FileDialog(me,message="Open file...",style=wx.OPEN|wx.MULTIPLE)			if d.ShowModal()<>OK:
				return CANCEL
			files=d.GetPaths()
		else:
			files=[file]
		
		if not me.doc_w_focus.modified and me.doc_w_focus.file==None and me.doc_w_focus.text.GetText()=='':
			me._close_n_no_new()
						
		for file in files:
			assert os.path.exists(file) #?? and race condition, file may disappear before me.doc_w_focus.open(file)
			file=os.path.abspath(file)
			doc_with_file_already_open=None
			for doc in me.docs:
				if fh.samefile(doc.file,file):
					doc_with_file_already_open=doc
					break
			if doc_with_file_already_open:
				me._expand(doc_with_file_already_open)
				fh.short_duration_status_text('File "%s" was already open'%os.path.basename(file))
			else:
				me.new()
				me.doc_w_focus.open(file)
				me._set_title()
				me._fix_doc_order_after_doc_w_focus_name_change()
		return OK
			
	def save(me):
		me.doc_w_focus.save()
		me._set_title()
		me._fix_doc_order_after_doc_w_focus_name_change()
	
	def save_as(me):
		me.doc_w_focus.save_as()
		me._set_title()
		me._fix_doc_order_after_doc_w_focus_name_change()
		
	def _set_title(me):
		title=''
		if fh.debug.ON:
			title+='[WARNING - DEBUG MODE IS ON] '
		if me.doc_w_focus.modified:
			title+='*** '
			
		if me.doc_w_focus.file==None:
			title+='Untitled'
		else:
			dir,file=os.path.split(me.doc_w_focus.file)
			
			title+=file
			
			ancestors=dir.split(os.sep) # ?? not kosher, does it break somewhere?
			i=-1
			if ancestors[i]=='':
				i-=1
			title+=' in '+ ancestors[i]
			i-=1
			try: title+=' > '+ ancestors[i]
			except IndexError:pass
		
		title+=' - Farmhand'
		me.GetParent().SetTitle(title)
		
	# - document event handlers
	
	def on_unsaved(me,e):
		if e.src<>me.doc_w_focus: # can this happen?
			return
		me._set_title()

	def on_doc_textbar_activate(me,e):
		if len(me.docs)==1:
			return
			
		if e.src.active:
			assert e.src.doc==me.doc_w_focus
		else:
			me._expand(e.src.doc)
		
	# - </document event handlers>
	
	def cut(me):     me.doc_w_focus.cut()
	def undo(me):    me.doc_w_focus.undo()
	def copy(me):    me.doc_w_focus.copy()
	def find(me):    me.doc_w_focus.show_find_dialog()
	def find_next(me): me.doc_w_focus.find()
	def find_prev(me): me.doc_w_focus.find(prev=True)
	def redo(me):    me.doc_w_focus.redo()
	def paste(me):   me.doc_w_focus.paste()
	def set_eol_mode(me,mode): me.doc_w_focus.set_eol_mode(mode)